
/* arm.h - ARM CPU flags etc */

/* Copyright 1996-2005 Wind River Systems, Inc. */

/*
modification history
--------------------
01o,10oct05,scm  correct SPR 111664
01n,04apr05,jb   Adding ARMARCH6 and 1136 support
01m,21mar05,mdo  Add define for ansiMath testing
01l,02mar05,mdo  Add prototype for __ieee_status() and definitions for
                 exception flags
01k,10aug04,scm  remove MPU support...
01j,25nov03,sn   Avoid gcc 3.3.2 preprocessor token pasting error
01i,26aug03,rec  remove SYS_PWR_MGMT conditional
01h,07jul03,rec  revert to non-portable kernel
01g,01jul03,rec  code review comments
01f,28may03,rec  Power Management
01f,17dec02,jb  Adding ARM10 and 926E support
01e,15jan02,m_h  ARMARCH5 thumb problem
01d,05nov01,t_m  remove leading underscores via FUNC/VAR macros
01c,05nov01,t_m  Undo underscores
01b,19jul01,ed   Fixing to be compatible with Diab compiler.
01d,17oct01,t_m  Merge in DIAB 
01c,10oct01,jb  Enabling removal of pre-pended underscores for new compilers
                 (Diab/Gnu elf)
01b,23jul01,scm  change XScale name to conform to coding standards...
01a,11dec00,scm  replace references to ARMSA2 with XScale
01g,16oct00,scm  reverse back I & F bits for SA2
01f,01sep00,scm  add sa2 support...
01e,08feb99,jpd  added further MMU/CACHE types.
01d,20jan99,cdp  removed support for old ARM libraries.
01c,24aug98,cdp  added MMU/cache types, ARM_HAS_MPU/ARM_THUMB, ARMST16/ARMST32.
01b,21aug97,cdp  added _?_FUNCTION macros and HAS_HALFWORD_
01a,08may96,cdp  written
*/

#ifndef	__INCarmh
#define	__INCarmh

#ifdef __cplusplus
extern "C" {
#endif

/* Make sure excArmLib.h also has same settings */

/* bits in the PSR */

#define	V_BIT	(1<<28)
#define	C_BIT	(1<<29)
#define	Z_BIT	(1<<30)
#define	N_BIT	(1<<31)
#define I_BIT   (1<<7)
#define F_BIT   (1<<6)
#define	T_BIT	(1<<5)


/* mode bits */

#define MODE_SYSTEM32	0x1F
#define MODE_UNDEF32	0x1B
#define	MODE_ABORT32	0x17
#define MODE_SVC32	0x13
#define MODE_IRQ32      0x12
#define MODE_FIQ32      0x11
#define MODE_USER32	0x10


/* masks for getting bits from PSR */

#define MASK_MODE	0x0000003F
#define	MASK_32MODE	0x0000001F
#define	MASK_SUBMODE	0x0000000F
#define MASK_INT	0x000000C0
#define	MASK_CC		0xF0000000


/* shifts to access bits in the PSR */

#define INT_MASK_SHIFT	6


/* The coprocessor number of the MMU System Control Processor */

#define CP_MMU 15


/* ARM MMU types */

#define ARMMMU_NONE	0
#define ARMMMU_710A	1
#define ARMMMU_810	2
#define ARMMMU_SA110	3
#define ARMMMU_940T	4
#define ARMMMU_740T	5
#define ARMMMU_SA1100	6
#define ARMMMU_SA1500	7
#define ARMMMU_720T	8
#define ARMMMU_920T	9
#define ARMMMU_946E     10
#define ARMMMU_XSCALE   11
#define ARMMMU_926E	12
#define ARMMMU_1020E	13
#define ARMMMU_1022E	14
#define ARMMMU_1136JF   15

/* ARM cache types */

#define ARMCACHE_NONE	0
#define ARMCACHE_710A	1
#define ARMCACHE_810	2
#define ARMCACHE_SA110	3
#define ARMCACHE_940T	4
#define ARMCACHE_740T	5
#define ARMCACHE_SA1100	6
#define ARMCACHE_SA1500	7
#define ARMCACHE_720T	8
#define ARMCACHE_920T	9
#define ARMCACHE_946E   10
#define ARMCACHE_XSCALE 11
#define ARMCACHE_926E	12
#define ARMCACHE_1020E	13
#define ARMCACHE_1022E	14
#define ARMCACHE_1136JF	15


/* check CPU/cache/MMU features */


/* Cache Line sizes */

#undef _CACHE_ALIGN_SIZE
#define _CACHE_ALIGN_SIZE 32


#if (CPU == ARMARCH3)
#define ARM_HAS_HALFWORD_INSTRUCTIONS FALSE
#else
#define ARM_HAS_HALFWORD_INSTRUCTIONS TRUE
#endif

#if 0
#if defined(ARMMMU) && \
 ((ARMMMU == ARMMMU_940T) || (ARMMMU == ARMMMU_740T) || (ARMMMU == ARMMMU_946E))
#define ARM_HAS_MPU TRUE
#else
#define ARM_HAS_MPU FALSE
#endif
#else
#define ARM_HAS_MPU FALSE  /* remove support for MPU's */
#endif

#if defined(ARMMMU) && (ARMMMU == ARMMMU_NONE)
#define ARM_HAS_NO_MMU TRUE
#else
#define ARM_HAS_NO_MMU FALSE
#endif

#if (CPU == ARMARCH4_T) || (CPU == ARMARCH5_T)
#define ARM_THUMB TRUE
#else
#define ARM_THUMB FALSE
#endif


/** Power management for XSCALE **/

#if (CPU==XSCALE) 

/* The coprocessor number of the Power Mode Register */

#define CP_CCLKCFG      14

/* OPCODE for idle */

#define PWRMODE_IDLE    1

#endif  /* Power management for XSCALE */

/** Power management for ARM **/

#if (CPU==ARMARCH5) || (CPU==ARMARCH5_T) || (CPU==ARMARCH6)

/* The coprocessor number of the Power Mode Register */

#define CP_CORECTL      15

/* OPCODE for idle */

#define PWRMODE_IDLE    1

#endif  /* Power management for ARMARCH5 */

/* Define __ieee_status exception flags */
#define FE_IEEE_FLUSHZERO		    (0x01000000)
#define FE_IEEE_ROUND_TONEAREST		(0x00000000)
#define FE_IEEE_ROUND_UPWARD		(0x00400000)
#define FE_IEEE_ROUND_DOWNWARD		(0x00800000)
#define FE_IEEE_ROUND_TOWARDZERO	(0x00C00000)
#define FE_IEEE_ROUND_MASK		    (0x00C00000)
#define FE_IEEE_MASK_INVALID		(0x00000100)
#define FE_IEEE_MASK_DIVBYZERO		(0x00000200)
#define FE_IEEE_MASK_OVERFLOW		(0x00000400)
#define FE_IEEE_MASK_UNDERFLOW		(0x00000800)
#define FE_IEEE_MASK_INEXACT		(0x00001000)
#define FE_IEEE_MASK_ALL_EXCEPT		(0x00001F00)
#define FE_IEEE_INVALID			    (0x00000001)
#define FE_IEEE_DIVBYZERO		    (0x00000002)
#define FE_IEEE_OVERFLOW		    (0x00000004)
#define FE_IEEE_UNDERFLOW		    (0x00000008)
#define FE_IEEE_INEXACT			    (0x00000010)
#define FE_IEEE_ALL_EXCEPT		    (0x0000001F)
#ifndef _ASMLANGUAGE
extern unsigned int __ieee_status (unsigned int mask, unsigned int flags);
#endif

/* Define for ansiMath Testing */
#define _WRS_ARM_IEEE_STATUS

#ifdef _ASMLANGUAGE

#if FALSE 

/* Build for old coff compiler */
#define FUNC(a) _##a
#define VAR(name) _##name

#define FUNC_LABEL(func)      FUNC(func)##:
#define VAR_LABEL(name)               VAR(name)##:

#if ARM_THUMB
#define _ARM_FUNCTION_CALLED_FROM_C(a) \
	.code	16	;\
	.balign	4	;\
	.thumb_func	;\
_##a:			;\
	BX	pc	;\
	NOP		;\
	.code	32	;\
A_##a:
#else
#define _ARM_FUNCTION_CALLED_FROM_C(a) \
	.code	32	;\
	.balign	4	;\
_##a:
#endif

#define _ARM_FUNCTION(a)	\
	.code	32	;\
	.balign	4	;\
_##a:

#if ARM_THUMB
#define _THUMB_FUNCTION(a)	\
	.code	16	;\
	.balign	2	;\
	.thumb_func	;\
_##a:
#endif

#else

/* Build for Gnu elf or Diab compiler */
/* useful, assembly-language macros */
#define FUNC(a) a
#define VAR(name) name

#define FUNC_LABEL(func)      func:
#define VAR_LABEL(name)               name:

#if ARM_THUMB 
#define _ARM_FUNCTION_CALLED_FROM_C(a) \
	.code	16	;\
	.balign	4	;\
	.thumb_func	;\
a:			;\
	BX	pc	;\
	NOP		;\
	.code	32	;\
A##a:
#else
#define _ARM_FUNCTION_CALLED_FROM_C(a) \
	.code	32	;\
	.balign	4	;\
a:
#endif

#define _ARM_FUNCTION(a)	\
	.code	32	;\
	.balign	4	;\
a:

#if ARM_THUMB
#define _THUMB_FUNCTION(a)	\
	.code	16	;\
	.balign	2	;\
	.thumb_func	;\
a:
#endif

#endif  /* GNU elf or DIAB*/ 

/** I80310 (coyanosa) specific helper macros **/
#if ((CPU==XSCALE) || (CPU==ARMSA110))
/*
 * The following macro should be used when software needs to be assured that a
 * CP15 update has taken effect. It may only used while in a privileged mode,
 * because it accesses CP15. Ref. Coyanosa EAS 2.3.4 Additions to CP15
 * functionality
 */
#define CPWAIT(a) \
    mrc         p15, 0, a, c2, c0, 0  /* arbitrary read of CP15 */ ;\
    mov         a, a                  /* wait for it */ ;\
    sub         pc, pc, IMMED4            /* branch to next instruction */ ;
#define IMMED4  #4    
		
/*
 * at this point, any previous CP15 writes are guaranteed
 * to have taken effect
 */

 
/*
 * The following macro should be used when software needs to be assure that
 * BCU has finish all outstanding operations.
 */
 
/*
 * CAUTION: This macro should be used only from the cacheable region, or it may
 * keep the BCU eternally busy fetching the code.
 */

#define BCUWAIT(a) \
    mrc		p13, 0, a, c0, c1, 0; /* Read BCUCTL,updates conditon code */ \
    submi       pc, pc, IMMED12 ;          /* If BCU busy (bit 31 set) try again */
#define IMMED12  #12    
 
#endif /* if CPU=XSCALE */


#endif	/* _ASMLANGUAGE */

#ifdef __cplusplus
}
#endif

#endif	/* __INCarmh */
